<template>
  <EditableParamObj
    v-if="paramItem.param_type=='Obj' && bIsEffectEditParamLayoutShow && _isHasOwnProperty(parentVal, paramKey)"
    :key="compId + '_' + parentKeys.join('_') + '_' + paramKey"
    :compId="compId"
    :paramItem="paramItem"
    :paramKey="paramKey"
    :paramVal="paramVal"
    :parentKeys="parentKeys"
    :parentVal="parentVal"
    :original="original"
    :editableParamsLists="editableParamsLists"
    :editableParamsLists4Add="editableParamsLists4Add"
    :type="type"
    @success="val => onChange(val)">
  </EditableParamObj>
  <EditableParamLists
    v-else-if="paramItem.param_type=='Lists' && bIsEffectEditParamLayoutShow && _isHasOwnProperty(parentVal, paramKey)"
    :key="compId + '_' + parentKeys.join('_') + '_' + paramKey"
    :compId="compId"
    :paramItem="paramItem"
    :paramKey="paramKey"
    :paramVal="paramVal"
    :parentKeys="parentKeys"
    :parentVal="parentVal"
    :original="original"
    :editableParamsLists="editableParamsLists"
    :editableParamsLists4Add="editableParamsLists4Add"
    :type="type"
    @success="val => onChange(val)">
  </EditableParamLists>
  <component
    v-else-if="bIsEffectEditParamLayoutShow && _isHasOwnProperty(parentVal, paramKey)"
    :key="compId + '_' + parentKeys.join('_') + '_' + paramKey"
    :param_id="compId + '_' + parentKeys.join('_') + '_' + paramKey"
    :is="paramItem.param_type"
    v-bind="_paramItem"
    :value="_newParamVal"
    :modelValue="_newParamVal"
    @change="val => onChange(val)">
  </component>
</template>

<script>
  import EditNormalComponentsGather from '@/views/card/js/mixins/edit-normal-components-gather.js';
  import { fileUploadUrl, fileUploadS3Url } from "@/api/api";
  import { _getDeepParamVal, isArray, isUndefined, isString, isHasOwnProperty, isArrayEquals } from '@/utils/public.js';
  import { defineAsyncComponent } from 'vue';
  import { mapState } from 'vuex'
  export default {
    name: 'editableParam',
    mixins: [EditNormalComponentsGather],
    data() {
      return {
        fileUploadUrl: _.cloneDeep(fileUploadUrl),
        fileUploadS3Url: _.cloneDeep(fileUploadS3Url),

        tempParamItem: null,
      }
    },
    props: [
      'compId',
      'paramItem',
      'paramKey',
      'paramVal',
      'parentKeys',
      'parentVal',
      'original',
      'editableParamsLists',
      'editableParamsLists4Add',
      'type'
    ],
    emits: ['change'],
    computed: {
      ...mapState({
        site_id: state => state.cardComponents.siteData.id,
        pageInfo: state => _.cloneDeep(state.cardComponents.siteData.attrs),
        fileUploadData: state => state.components.fileUploadData,
      }),

      /* param */
      _newParamVal() {
        // 1. type == ImageNormal
        if(this.paramItem.param_type == 'ImageNormal' && this.paramItem.res_type == 'Array') return '';
        if(this.paramItem.param_type == 'ImagePidNormal') return '';

        // 2. return
        return this.paramVal;
      },
      _paramItem: {
        get() {
          let newParamItem = _.cloneDeep(this.tempParamItem);

          // 1. type == ImageNormal
          if(newParamItem.param_type == 'ImageNormal') {
            // 1.1 action / data 必须参数设置
            newParamItem.action = this.fileUploadUrl;
            newParamItem.data = this.fileUploadData;

            // 1.2 res_type == Array => fileList
            if(newParamItem.res_type == 'Array') {
              const newArrVal = this.paramVal;
              newParamItem.fileList = isArray(newArrVal) && newArrVal.map(item => {
                return {
                  name: '',
                  url: item
                };
              });
            }
            // 1.3 res_type == String => value
            else {
              newParamItem.value = this.paramVal;
              newParamItem.modelValue = this.paramVal;
            }
          }
          // 2. type == ImagePidNormal
          else if(newParamItem.param_type == 'ImagePidNormal') {
            // 2.1 action / data 必须参数设置
            newParamItem.action = this.fileUploadS3Url;
            newParamItem.data = {
              siteid: this.site_id,
            };

            // 2.2 fileList
            // const newArrVal = this.paramVal;
            newParamItem.fileList = isArray(this.paramVal) && this.paramVal.map(item => item);
          }
          // 3. type == Action
          else if(newParamItem.param_type == 'Action') {
            if( this.type &&
              ( this.type == 'CARD_16' ||
                this.type == 'CARD_6' ||
                this.type == 'CARD_27' ||
                this.type == 'CARD_8' ||
                this.type == 'CARD_JY0005216' ) ) {
                  let newArrKeys = _.cloneDeep( this.parentKeys );
                  newArrKeys.pop();
                  let newButton = _getDeepParamVal(this.original, newArrKeys);
                  newParamItem.button = newButton;
            }
          }

          // com_id
          newParamItem.com_id = this.compId;

          newParamItem.disabled = typeof newParamItem.disabled === "boolean" ? newParamItem.disabled
            : newParamItem.disabled === "true" ? true
            : false;

          return newParamItem;
        },
        set(val) {
          this.tempParamItem = val;
        }
      },

      // _paramItem() {
      //
      // },

      /* param_effect_parent */
      bIsEffected() {
        return this.paramItem && this.paramItem.param_effect_parent;
      },
      curEffectParentVal() {
        // 1. param_effect_parent 不存在
        if(!this.bIsEffected) return;

        // 2. param_effect_parent 存在；
        //    获取 effect_parent_keys 对应的值
        //    TODO: effect_parent_keys 存在  ？
        //    ‘ARRAY_NUM’ 同于处理 数组数据 的键
        let effect_parent_keys = this.paramItem.param_effect_parent.effect_parent_keys;
        effect_parent_keys = effect_parent_keys.map((key, index) => {
          if(key === 'ARRAY_NUM') return isUndefined(this.parentKeys[index]) ? key : this.parentKeys[index];
          return key;
        })
        if( !isArray( effect_parent_keys ) || effect_parent_keys.length <= 0 ) return;
        const _curEffectParentVal = _getDeepParamVal(this.original, _.cloneDeep(effect_parent_keys));
        if(_curEffectParentVal && _curEffectParentVal.message && _curEffectParentVal.message=='EndIterative') return;

        return _curEffectParentVal;
      },
      bIsEffectEditParamLayoutShow() {
        // 1. param_effect_parent 不存在
        if(!this.bIsEffected) return true;

        // 2. param_effect_parent 存在；
        const { effect_parent_val, effect_type } = this.paramItem.param_effect_parent;
        if( effect_parent_val == this.curEffectParentVal ) return true;
        else if( effect_type.indexOf( 'SHOW_HIDE' ) > -1 ) return false;
        else return true;
      },
      bIsEffectObjChangeParams() {
        // 1. param_effect_parent 不存在
        if(!this.bIsEffected) return false;

        // 2. param_effect_parent 存在；
        const effect_type = this.paramItem.param_effect_parent.effect_type;
        const effect_obj_params = this.paramItem.param_effect_parent.effect_obj_params;
        if( effect_obj_params &&
          isArray(effect_obj_params) &&
          effect_type.indexOf( 'CHANGE_PARAMS' ) > -1 ) return true;
        return false;
      },
    },
    components: {
      'EditableParamObj': defineAsyncComponent(() => import('@/views/card/components/recursion/EditableParamObj.vue')),
      'EditableParamLists': defineAsyncComponent(() => import('@/views/card/components/recursion/EditableParamLists.vue')),
    },
    beforeMount() {
      // init set paramItem
      this.initSetParamsItem();
    },
    methods: {
      onChange(val) {
        let newParentVal = _.cloneDeep(this.parentVal);
        // let newParentVal = this.parentVal;
        newParentVal[this.paramKey] = val;
        this.$emit('change', newParentVal);
      },

      /* init */
      initSetParamsItem() {
        this.tempParamItem = _.cloneDeep(this.paramItem);
      },

      /* 工具类：数据处理 */
      _isHasOwnProperty(obj, key) {
        return isHasOwnProperty(obj, key);
      },
    },
    watch: {
      curEffectParentVal: {
        // deep: true,
        immediate: false,
        handler(newVal, oldVal) {
          // 0. curEffectParentVal 为 undefined，则不触发
          if (typeof this.curEffectParentVal === 'undefined') return;

          // 1. param_effect_parent 不存在
          if(!this.bIsEffected) return;

          // 2. param_effect_parent 存在
          const { effect_type, effect_parent_val, effect_clear, effect_list_vals, effect_cofing, effect_copy } = this.paramItem.param_effect_parent;
          if( effect_type.indexOf('INIT') > -1 ) {
            if(effect_clear)
              this.onChange(effect_clear.effect_clear_default_val);
            if(effect_list_vals && typeof effect_list_vals[newVal] != 'undefined')
              this.onChange(effect_list_vals[newVal]);  // undefined: 表示未设置，不改变
          }
          if( effect_type.indexOf('SHOW_HIDE') > -1 ) {
            // 2.1 if SHOW_HIDE ?
            if(this.curEffectParentVal == effect_parent_val) {
              // 2.1.0. do nothing
              // 防止 数组添加时 清空数组
            }
            else {
              // 2.1.2. update
              if(effect_clear) this.onChange(effect_clear.effect_clear_default_val);
            }
          }
          if( effect_type.indexOf('ADD_ITEM') > -1 ) {
            // 2.2 if ADD_ITEM ?
            if(this.paramItem.param_type == 'Lists') {
              if(effect_clear) this.onChange(effect_clear.effect_clear_default_val);
            }
          }
          if( effect_type.indexOf('CHANGE_PARAMS') > -1 ) {
            // 2.3 if CHANGE_PARAMS ?
            if(this.paramItem.param_type == 'Obj' && this.bIsEffectObjChangeParams) {
              // 2.3.1 取 effect_obj_params => effect_new_obj_params
              let newParamsObj;
              const effect_obj_params = this.paramItem.param_effect_parent.effect_obj_params;
              const new_effect_obj_params = effect_obj_params.filter((param) => {
                return param.effect_regular.test(this.curEffectParentVal)
              });
              if(new_effect_obj_params.length <= 0) newParamsObj = null;
              else newParamsObj = new_effect_obj_params[0].effect_new_obj_params;

              // 2.3.2 update
              this.onChange(newParamsObj);
            }
          }
          if( effect_type.indexOf('COPY') > -1 ) {
            // 2.4 if COPY ? 复制 effect_parent_val 到 pKey 上
            let strNewVal = newVal;

            // 2.4.1 是否存在 effect_copy ？
            if(effect_copy) {
              if( isString( effect_copy.prefix ) && effect_copy.prefix != '' ) strNewVal = effect_copy.prefix + strNewVal;
              if( isString( effect_copy.suffix ) && effect_copy.suffix != '' ) strNewVal = strNewVal + effect_copy.suffix;
            }

            // 2.4.2 update
            this.onChange(strNewVal);
          }
          if( effect_type.indexOf('MID_JOIN') > -1 ) {
            // 2.5.1 effect_mid_join_key
            const { key: effect_mid_join_key } = this.paramItem.param_effect_parent.effect_mid_join;
            let strMidJoin = '';

            // 2.5.2 ⚠️！：注意比较数组相同
            if( isArray(newVal) && !isArrayEquals(oldVal, this.curEffectParentVal) ) {
              // 2.5.3 拼接 mid
              newVal.forEach((item) => {
                if( isHasOwnProperty(item, effect_mid_join_key) ) {
                  strMidJoin += ( item[effect_mid_join_key] + ',' );
                }
                else strMidJoin += ',';
              });

              // 2.5.4 更新
              this.onChange(strMidJoin);
            }
          }
          if( effect_type.indexOf('CHANGE_CONFIG') > -1 ) {
            if(effect_cofing && typeof effect_cofing[newVal] === "object") {
              this._paramItem = {
                ...this._paramItem,
                ...effect_cofing[newVal],
              };
            }
          }
        },
      },
    },
  }
</script>

<style lang="scss"></style>
